Skip to content

[SYCL][Graph] Implement dynamic local accessors #18437

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: sycl
Choose a base branch
from

Conversation

fabiomestre
Copy link
Contributor

@fabiomestre fabiomestre commented May 13, 2025

  • Implements the dynamic_local_accessor class with compiler support.
  • Refactor the recently added dynamic_work_group_memory class to only use one impl member variable. This brings it closer to the design of other sycl classes and avoids future ABI break issues.
  • There are 2 ABI breaking changes. However, they are both related to the dynamic_work_group_memory class whose specification has not been merged yet and is not yet officially supported.

@fabiomestre fabiomestre changed the title Implement dynamic local accessors [SYCL][Graph] Implement dynamic local accessors May 13, 2025
@fabiomestre fabiomestre force-pushed the fabio/v2_dynamic_local_accessor_impl branch from 56eaa40 to 32945a2 Compare May 13, 2025 12:23
@fabiomestre fabiomestre force-pushed the fabio/v2_dynamic_local_accessor_impl branch from 00f1bbf to da31888 Compare May 13, 2025 14:02
@fabiomestre fabiomestre force-pushed the fabio/v2_dynamic_local_accessor_impl branch from db1d142 to 19e107c Compare May 13, 2025 18:16
@fabiomestre fabiomestre marked this pull request as ready for review May 13, 2025 18:43
@fabiomestre fabiomestre requested review from a team as code owners May 13, 2025 18:43
* Implements the dynamic_local_accessor class with compiler support.
* Refactor the recently added dynamic_work_group_memory class to
only use one impl member variable. This brings it closer to the
design of other sycl classes and avoids future ABI break issues.
@fabiomestre fabiomestre force-pushed the fabio/v2_dynamic_local_accessor_impl branch from 19e107c to cb78e9d Compare May 13, 2025 19:08
Copy link
Contributor

@EwanC EwanC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple comments from a first pass

{
}

local_accessor<DataT, Dimensions> get() const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the spec PR I don't think we say this method is const, so that is something to update in the spec

@@ -623,9 +629,15 @@ __SYCL_TYPE(dynamic_work_group_memory) dynamic_work_group_memory
/// @param Graph The graph associated with this object.
/// @param Num Number of elements in the unbounded array DataT.
dynamic_work_group_memory(
experimental::command_graph<graph_state::modifiable> Graph, size_t Num)
[[maybe_unused]] experimental::command_graph<graph_state::modifiable>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If some of the jenkins jobs are still using gcc 7.5, then those [[maybe_unused]] in the constructor will cause a failure because of a gcc bug, see #17736

But I guess it will show up on the pre-commit CI too. Maybe the gcc version was bumped already.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed both dynamic_work_group_memory and dynamic_local_accessor to use a solution similar to the one in #17736

Thanks for pointing this out!

[[maybe_unused]] ext::oneapi::experimental::dynamic_work_group_memory<
DataT, PropertyListT> &DynWorkGroupMem) {

#ifndef __SYCL_DEVICE_ONLY__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this required for dynamic work group memory but not the existing work group mem set_arg() which looks to be doing basically the same thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because dynamic_work_group_memory_base does not exist for device code. I also think it is good practice to make clear that this code does nothing for device compilation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think it is good practice to make clear that this code does nothing for device compilation.

I don't know that I agree with this. Much of the runtime implementation is not relevant for device compilation but guarding everything would be impractical.

Is there a reason we can't make the base class available on device and just guard the impl that actually does the host work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that guarding the impl would increase the amount of #ifdefs that need to be added to extend the base class to the device (e.g. different versions of constructors when creating the impl and when not). Doing it this way, we can keep the #ifdefs restricted to the dynamic_work_group_memory / dynamic_local_accessor class and the base classes will be cleaner. So it's mostly a matter of choosing where to have the noisy #ifdefs I think.

In the end, I think it's a matter of preference. But more importantly, I also chose this way because it's the way that local_accessor / accessor are implemented. For example:


  // setArgHelper for local accessor argument (legacy accessor interface)
  template <typename DataT, int Dims, access::mode AccessMode,
            access::placeholder IsPlaceholder>
  void setArgHelper(int ArgIndex,
                    accessor<DataT, Dims, AccessMode, access::target::local,
                             IsPlaceholder> &&Arg) {
    (void)ArgIndex;
    (void)Arg;
#ifndef __SYCL_DEVICE_ONLY__
    setLocalAccessorArgHelper(ArgIndex, Arg);
#endif
  }

  // setArgHelper for local accessor argument (legacy accessor interface)
  template <typename DataT, int Dims, access::mode AccessMode,
            access::placeholder IsPlaceholder>
  void setArgHelper(int ArgIndex,
                    accessor<DataT, Dims, AccessMode, access::target::local,
                             IsPlaceholder> &&Arg) {
    (void)ArgIndex;
    (void)Arg;
#ifndef __SYCL_DEVICE_ONLY__
    setLocalAccessorArgHelper(ArgIndex, Arg);
#endif
  }

I could also move the #ifdef to setArgHelper to have the same pattern as accessor / local_accessor?

Comment on lines 30 to 31
// Check that registering a dynamic object with a node from a graph that was
// not passed to its constructor throws.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't make sense now since it is checking that it doesn't throw. The error for this was removed in #18199 .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I messed up the rebase. The code on origin still has the comment but slightly changed. I will update to match what is in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants